package com.ellwood.copyright.common.core.utils.excel;

import com.ellwood.copyright.common.core.annotation.ExcelFieldConverter;
import com.ellwood.copyright.common.core.annotation.ExcelHeader;
import com.ellwood.copyright.common.core.constant.FieldConverter;
import com.ellwood.copyright.common.core.enums.EnumConverter;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

/**
 * @ProjectName: ell-copyright-pro
 * @PackageName: com.ellwood.copyright.common.core.utils.excel
 * @ClassName: ExcelExportUtil
 * @Description: // ExcelExportUtil 是用来导出 Excel 数据的工具类，负责读取 DTO/VO 中的注解并进行字段值转换。
 * @Author: Ellwood
 * @CreateDate: 2024/12/23 - 14:21
 * @Version: V1.0.0
 */
public class ExcelExportUtil {

    /**
     * 导出Excel工具函数
     * @param dataList 数据集合
     * @param clazz 类型
     * @param fileName 文件名
     * @param <T> 实体
     * @throws IOException 异常
     */
    public static  <T> void exportToExcel(List<T> dataList, Class<T> clazz, String fileName) throws IOException  {
        Workbook workbook = new XSSFWorkbook();
        Sheet sheet = workbook.createSheet("sheet1");

        // 创建表头
        createHeaderRow(sheet, clazz);

        // 填充数据
        fillDataRows(sheet, dataList, clazz);

        // 写入到文件
        try(FileOutputStream fileOut=new FileOutputStream(new File(fileName))) {
            workbook.write(fileOut);
        }

        workbook.close();
    }

    /**
     * 填充数据
     * @param sheet sheet
     * @param dataList 数据
     * @param clazz 类型
     * @param <T> 实体
     */
    private static <T> void fillDataRows(Sheet sheet, List<T> dataList, Class<T> clazz) {
        int rowIndex = 1;

        for (T data : dataList) {
            Row row = sheet.createRow(rowIndex++);
            Field[] fields = clazz.getDeclaredFields();
            int cellIndex=0;

            for (Field field : fields) {
                if (field.isAnnotationPresent(ExcelHeader.class)) {
                    field.setAccessible(true);
                    try{
                        Object value = field.get(data);

                        // 判断是否是日期类型，如果是，进行格式化
                        if (value instanceof Date) {
                            SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd");
                            value = sdf.format((Date) value);
                        }

                        // 使用转换器注解来处理字段的转换
                        if (field.isAnnotationPresent(ExcelFieldConverter.class)) {
                            ExcelFieldConverter converterAnnotation  = field.getAnnotation(ExcelFieldConverter.class);
                            FieldConverter converter = converterAnnotation.converter()
                                    .getConstructor(EnumConverter.class)
                                    .newInstance(getEnumForField(field.getName()));

                            value = converter.convert(value);
                        }

                        // 对于枚举类型字段（如 gender 和 isState），进行转换为对应文字
                        if (field.getName().equals("gender") || field.getName().equals("isState")) {
                            // 获取对应的枚举类型
                            EnumConverter enumConverter = getEnumForField(field.getName());
                            // 处理枚举转换
                            if (value instanceof Integer) {
                                value = enumConverter.convert((Integer) value);
                            }
                        }

                        // 在单元格中填充数据，确保为字符串类型
                        row.createCell(cellIndex++).setCellValue(value != null ? value.toString() : "");
                    }catch (IllegalAccessException | InstantiationException | NoSuchMethodException |
                            InvocationTargetException e){
                        e.printStackTrace();
                    }
                }
            }
        }
    }

    /**
     * 根据字段名称动态获取枚举类型
     * @param fieldName 名称
     * @return 返回结果
     */
    private static EnumConverter getEnumForField(String fieldName) {
        if ("gender".equals(fieldName)) {
            return EnumConverter.GENDER;
        } else if ("isState".equals(fieldName)) {
            return EnumConverter.STATUS;
        }

        return null;
    }

    /**
     * 创建表头
     * @param sheet sheet
     * @param clazz 类型
     * @param <T>  实体
     */
    private static <T> void createHeaderRow(Sheet sheet, Class<T> clazz) {
        Row headerRow=sheet.createRow(0);
        Field[] fields = clazz.getDeclaredFields();
        int cellIndex=0;

        for (Field field : fields) {
            if (field.isAnnotationPresent(ExcelHeader.class)) {
                ExcelHeader headerAnnotation = field.getAnnotation(ExcelHeader.class);
                headerRow.createCell(cellIndex++).setCellValue(headerAnnotation.value());
            }
        }

    }

}
